package com.xinpan.exercise;
/*
 * Subsets II
Given a collection of integers that might contain duplicates, S, return all possible subsets.

Note:
Elements in a subset must be in non-descending order.
The solution set must not contain duplicate subsets.
For example,
If S = [1,2,2], a solution is:

[
  [2],
  [1],
  [1,2,2],
  [2,2],
  [1,2],
  []
]
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class SubSets2 {
    public ArrayList<ArrayList<Integer>> subsetsWithDup(int[] num) {
        // Start typing your Java solution below
        // DO NOT write main() function
        ArrayList<ArrayList<Integer>> resList = new 
            ArrayList<ArrayList<Integer>>();
        if(num.length == 0)
            return resList;
            
        Arrays.sort(num);
        Set<ArrayList<Integer>> res = new 
            HashSet<ArrayList<Integer>>();
        
        int[] mask = new int[num.length];
        for(int i = 0; i < mask.length; i++)
            mask[i] = 0;
        
        subSetsHelper(mask, 0, res, num);

        resList.addAll(res);
        return resList;
    }
    
    public void subSetsHelper(int[] mask, int i, Set<ArrayList<Integer>> res,
                                int[] S)
    {
        if(i == mask.length)
        {
            ArrayList<Integer> aRes = new ArrayList<Integer>();
            for(int j = 0; j < mask.length; j++)
            {
                if(mask[j] == 1)
                    aRes.add(S[j]);
            }
            res.add(aRes);
            return;
        }
        
        mask[i] = 0;
        subSetsHelper(mask, i+1, res, S);
        mask[i] = 1;
        subSetsHelper(mask, i+1, res, S);
    }
}
